package com.jse.io.nio.network.old;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.concurrent.CountDownLatch;

import org.apache.log4j.Logger;
import org.junit.Test;

public class MutiClientTest {
	public final Logger mylog = Logger.getLogger(getClass());
	
	/**
	 * 服务器ip映射
	 * @throws Exception
	 */
	@Test
	public void testServerSocketIp() throws Exception {
		Thread t1 = new MySocketServer();
		t1.start();
		Thread.sleep(2000);
		
		try {
			//服务器指定了本机的ip地址，就不能用
			Socket client = new Socket("10.28.2.186", 99);
			//服务器指定了本机的ip地址，就不能用127.0.0.1或者localhost，否则抛出ConnectException：Connection refused: connect
//			Socket client = new Socket("127.0.0.1", 99);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 一个服务端，多个客户端测试
	 */
	@Test
	public void testOneToMany() throws Exception {
		CountDownLatch latch = new CountDownLatch(50);
		Thread t1 = new Server();
		t1.start();
		
		Thread.sleep(2000);
		
		for (int i = 0; i < 50; i++) {
			Thread t = new Client(latch);
			t.start();
		}
		
		Thread.sleep(10000);
		latch.await();
	}
	
	
	
	class Client extends Thread {
		private CountDownLatch latch;
		
		public Client() {}
		
		public Client(CountDownLatch latch) {
			this.latch = latch;
		}
		
		@Override
		public void run() {
			try {
				//构造函数已经调用了connection函数，发起连接请求，如果成功，底层就会有个与服务器端发生连接的clientfd（客户端文件描述）
				Socket clientfd = new Socket("127.0.0.1", 22);
				OutputStream output = clientfd.getOutputStream();
				output.write(String.valueOf((int)(Math.random() * 100)).getBytes());
				latch.countDown();
				output.close();
				clientfd.close();
			} catch (Exception e) {
				mylog.error("Client Socket is error", e);
			}
			
		}
	}
	
	class Server extends Thread {
		@Override
		public void run() {
			try {
				ServerSocket server = new ServerSocket();
				//只能绑定127.0.0.1ip地址
				SocketAddress address = new InetSocketAddress("127.0.0.1", 22);
				//公司本机ip
//				SocketAddress address = new InetSocketAddress("10.28.2.186", 22);
				server.bind(address);
				System.out.println(server);
				
				while (true) {
					//监听器文件描述建立连接后，调用accept服务端就返回连接的好的文件描述（参考《深入理解计算机系统》11.4.8章节）
					Socket connfd = server.accept();
					
					InputStream input = connfd.getInputStream();
					System.out.println("server received number : " + StreamUtil.getInput(input));
					//处理多个客户端直接在这里定义一个Worker线程，把connfd传入进去处理就可以了（参考http://javaman.group.iteye.com/group/wiki/3404-cuisuqiang-google-socket-InputStream-OutputStream）
				}
			} catch (IOException e) {
				mylog.error("server thread is error");
			}
		}
	}
	
	class MySocketServer extends Thread {
		@Override
		public void run() {
			try {
				ServerSocket server = new ServerSocket();
				SocketAddress address = new InetSocketAddress("127.0.0.1", 99);
				server.bind(address);
				
				Socket connfd = server.accept();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
